package com.generic.mybatis.dal.interceptor.automap.builder;

import com.generic.mybatis.dal.interceptor.automap.FieldMapper;
import com.generic.mybatis.dal.interceptor.automap.SqlBuilder;
import com.generic.mybatis.dal.interceptor.automap.TableMapper;
import com.generic.mybatis.dal.interceptor.automap.TableMapperHolder;
import com.google.common.base.Preconditions;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.ibatis.jdbc.SQL;
import org.apache.ibatis.mapping.MappedStatement;

import java.util.Map;

import static com.generic.mybatis.dal.interceptor.automap.builder.SqlBuilderUtil.buildIdWhereStatement;

/**
 * 更新 不为Null的字段
 *
 * @author wuaj
 */
public class UpdateBuilder implements SqlBuilder {

    @Override
    public String buildSql(MappedStatement mappedStatement, Class dtoClass, Object object) throws Exception {
        Preconditions.checkNotNull(object, "Sorry,I refuse to build sql for a null object!");

        TableMapper tableMapper = TableMapperHolder.getTableMapper(dtoClass);
        Map dtoFieldMap = PropertyUtils.describe(object);

        SQL sql = new SQL().UPDATE(String.format("%s as %s", tableMapper.getTableName(), tableMapper.getAlias()));

        boolean allFieldNull = true;
        for (Map.Entry<String, FieldMapper> fieldMapperEntry : tableMapper.getFieldMapperCache().entrySet()) {
            FieldMapper fieldMapper = fieldMapperEntry.getValue();
            Object value = dtoFieldMap.get(fieldMapper.getFieldName());

            if (value == null) continue;

            allFieldNull = false;
            sql.SET(String.format("%s = #{%s}", fieldMapper.getDbFieldName(), fieldMapper.getFieldName()));
        }

        if (allFieldNull) {
            throw new RuntimeException("Are you joking? Object " + object.getClass().getName()
                    + "'s all fields are null, how can i build sql for it?!");
        }

        buildIdWhereStatement(sql, tableMapper, dtoFieldMap);
        return sql.toString();
    }

}